package cn.zerlynn.sql.dialect.api;

import cn.zerlynn.sql.dialect.model.PageParam;
import cn.zerlynn.sql.dialect.model.SQLColumn;

import java.util.List;

public interface IFunction {
    /**
     * 转换列名，使其符合数据库的标识符语法。
     *
     * @param column 列名
     * @return 格式化后的列名
     */
    String formatColumn(String column);

    /**
     * 根据 SqlColumn 对象获取带别名的列表示形式。
     *
     * @param column SqlColumn 对象
     * @return 带别名的列名
     */
    String aliasColumn(SQLColumn column);

    /**
     * 计算绝对值。
     *
     * @param column 字段名
     * @return 绝对值的字符串表示
     */
    String abs(String column);

    /**
     * 四舍五入。
     *
     * @param column 字段名
     * @param scale  精度
     * @return 四舍五入后的字符串表示
     */
    String round(String column, int scale);

    /**
     * 向下取整。
     *
     * @param column 字段名
     * @return 向下取整后的字符串表示
     */
    String floor(String column);

    /**
     * 向上取整。
     *
     * @param column 字段名
     * @return 向上取整后的字符串表示
     */
    String ceil(String column);

    /**
     * 字符串拼接。
     *
     * @param strings 字符串列表
     * @return 拼接后的字符串
     */
    String concat(List<String> strings);

    /**
     * 截取子串。
     *
     * @param column 列名
     * @param start  开始位置
     * @param length 截取长度
     * @return 截取后的字符串
     */
    String substring(String column, int start, int length);

    /**
     * 获取字符串长度。
     *
     * @param column 列名
     * @return 字符串长度的字符串表示
     */
    String length(String column);

    /**
     * 获取当前日期。
     *
     * @return 当前日期的字符串表示
     */
    String currentDate();

    /**
     * 获取当前时间戳。
     *
     * @return 当前时间戳的字符串表示
     */
    String currentTimestamp();

    /**
     * 日期加法。
     *
     * @param column 列名
     * @param amount 数量
     * @param unit   单位（如天、月等）
     * @return 加法后的日期字符串表示
     */
    String dateAdd(String column, int amount, String unit);

    /**
     * 日期差。
     *
     * @param start 开始日期
     * @param end   结束日期
     * @param unit  单位（如天、月等）
     * @return 日期差的字符串表示
     */
    String dateDiff(String start, String end, String unit);

    /**
     * 生成 CASE WHEN 语句。
     *
     * @param conditions   条件列表
     * @param results      对应的结果列表
     * @param defaultValue 默认值
     * @return CASE WHEN 语句的字符串表示
     */
    String caseWhen(List<String> conditions, List<String> results, String defaultValue);

    /**
     * 计数。
     *
     * @param column 列名
     * @return 计数的字符串表示
     */
    String count(String column);

    /**
     * 求和。
     *
     * @param column 列名
     * @return 求和的字符串表示
     */
    String sum(String column);

    /**
     * 平均值。
     *
     * @param column 列名
     * @return 平均值的字符串表示
     */
    String avg(String column);

    /**
     * 最小值。
     *
     * @param column 列名
     * @return 最小值的字符串表示
     */
    String min(String column);

    /**
     * 最大值。
     *
     * @param column 列名
     * @return 最大值的字符串表示
     */
    String max(String column);

    /**
     * 应用分页。
     *
     * @param sql       SQL 查询语句
     * @param pageParam 分页参数
     * @return 带分页的 SQL 查询语句
     */
    String page(String sql, PageParam pageParam);

    /**
     * 判断是否为 NULL。
     *
     * @param column 列名
     * @return 是否为 NULL 的字符串表示
     */
    String isNull(String column);

    /**
     * 判断是否不为 NULL。
     *
     * @param column 列名
     * @return 是否不为 NULL 的字符串表示
     */
    String isNotNull(String column);

    /**
     * 转换为数值类型。
     *
     * @param column 列名
     * @param format 格式字符串
     * @return 转换后的数值类型的字符串表示
     */
    String toNumber(String column, String format);

    /**
     * 转换为字符类型。
     *
     * @param column 列名
     * @param format 格式字符串
     * @return 转换后的字符类型的字符串表示
     */
    String toChar(String column, String format);

    /**
     * 转换为日期类型。
     *
     * @param column 列名
     * @param format 格式字符串
     * @return 转换后的日期类型的字符串表示
     */
    String toDate(String column, String format);

    /**
     * 包装对象名带 schema。
     *
     * @param schema     schema 名
     * @param objectName 对象名
     * @return 包装后的对象名
     */
    String wrapWithSchema(String schema, String objectName);

    /**
     * 排序处理。
     *
     * @param columns   排序列名列表
     * @param ascending 是否升序
     * @return 排序的字符串表示
     */
    String orderBy(List<String> columns, boolean ascending);

    /**
     * 根据传入的格式，获取当前数据库的日期格
     * 比如oracle为YYYY-MM-DD，mysql为%Y-%m-%d
     *
     * @param format 统一的日期格式，如YYYY-MM-DD
     * @return 当前方言的数据库格式
     */
    String castFormat(String format);

}
